package com.example.slidecaptcha2;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.File;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author yyf900524
 * @date 2019/12/17
 */
@Component
public class VerifyCodeFactory {

    private static final Logger LOGGER = LoggerFactory.getLogger(VerifyCodeFactory.class);

    private static ConcurrentHashMap<String, Object> hashMap;

    @Resource
    private RedisUtil redisUtils;

    private static RedisUtil redisUtil;

    @PostConstruct
    public void init() {
        redisUtil = redisUtils;
    }

    public static synchronized Map<String, Object> getInstance(File templateFile, File targetFile) throws Exception {
        int count = 0;
        if (null == hashMap) {
            while (null == hashMap) {
                try {
                    hashMap = ImgVerifyCodeUtil.pictureTemplatesCut(templateFile, targetFile, "png", "jpg");
                    hashMap.put("time", System.currentTimeMillis());
                } catch (Exception e) {
                    count += 1;
                    if (count >= 5) {
                        throw new Exception("连续失败达到5次，" + e);
                    }
                }
            }
        } else {
            //如果对象有，判断时间，时间大于500ms异步生成新的，返回当前
            Long time = (Long) hashMap.get("time");
            if (System.currentTimeMillis() > time + 500) {
                //抢锁
                boolean getLocked = redisUtil.lock("locked", String.valueOf(System.currentTimeMillis() + 1000));
                if (getLocked) {
                    VerifyCodeFactory vF = new VerifyCodeFactory();
                    vF.AsyncGetPictureMap(templateFile, targetFile);
                }
            }
        }
        return hashMap;
    }

    /**
     * 异步获取图片
     *
     * @param templateFile
     * @param targetFile
     */
    @Async
    public void AsyncGetPictureMap(File templateFile, File targetFile) {
        ConcurrentHashMap<String, Object> map = null;
        int count = 0;
        while (null == map) {
            try {
                map = ImgVerifyCodeUtil.pictureTemplatesCut(templateFile, targetFile, "png", "jpg");
                hashMap = map;
                hashMap.put("time", System.currentTimeMillis());
            } catch (Exception e) {
                count += 1;
                if (count >= 5) {
                    System.out.println("异步过程连续失败次数达到5次，" + e);
                }
            }
        }
    }
}
